package com.yhy.wxzn.wms.job;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yhy.wxzn.common.enums.WmsMsgStatusEnums;
import com.yhy.wxzn.common.enums.WmsMsgTypeEnums;
import com.yhy.wxzn.common.exception.WmsBusinessException;
import com.yhy.wxzn.wcs.entity.WmsAsyncMsg;
import com.yhy.wxzn.wcs.service.IWmsAsyncMsgService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.util.SpringContextUtils;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Method;
import java.util.List;

/**
 * @Auther: 97354
 * @Date: 2023/11/1 16:19
 * @Description: WmsInboundJob
 * @Version 1.0.0
 * Wms入库定时任务
 */
@Slf4j
@DisallowConcurrentExecution
@PersistJobDataAfterExecution
public class WmsInboundJob implements Job {

    @Autowired
    private IWmsAsyncMsgService asyncMsgService;

    @SneakyThrows
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        log.info("-------------------入库定时任务开始执行----------------");
        LambdaQueryWrapper<WmsAsyncMsg> msgQuery = new LambdaQueryWrapper<>();
        msgQuery.eq(WmsAsyncMsg::getMsgStatus, WmsMsgStatusEnums.READY.getValue());
        /**
         *     MSG0(0,"刷新ASN状态", "wmsAsnDetailServiceImpl","refreshAsnStatus"),
         *     MSG1(1,"ASN分配", "wmsAsnServiceImpl","allocateBatch"),
         *     MSG2(2,"ASN分发", "wmsAsnServiceImpl","dispatchBatch"),
         *     MSG3(3,"Wcs扫码处理", "WmsBusinessMsgServiceImpl","doContainerBind"),
         *
         *      * 输送线任务下发时触发逻辑
         *
         * MSG4(4, "输送线任务完成逻辑-入库口", "WmsBusinessMsgServiceImpl", "dispatchTransmission"),
         *
         *      * 已经确定提升机在1楼并且是空闲状态，单车情景，提升机和小车在相同楼层
         *      * 此时只需要调度小车到提升机接驳点
         *
         *MSG5(5, "输送线任务完成逻辑-调度小车", "WmsBusinessMsgServiceImpl", "dispatchFourWayCarByLine"),
         *
         *      * 此时处理提升机不在1楼需调度小车跨层到1楼取货的场景
         *
         *MSG6(6, "生成提升机跨层任务-调度小车", "WmsBusinessMsgServiceImpl", "dispatchFourWayCarByElv"),
         */
        //处理除小车外的已=异步wcs上报任务
        msgQuery.lt(WmsAsyncMsg::getMsgType, 5);
        List<WmsAsyncMsg> msgs = asyncMsgService.list(msgQuery);
        if(CollectionUtils.isEmpty(msgs)){
            return;
        }
        for (WmsAsyncMsg msg:msgs) {
            executeInboundBusiness(msg);
        }
    }

    private void executeInboundBusiness(WmsAsyncMsg msg) {
        try {
            String jsonMsg = msg.getMsg();
            JSONObject jsonObject = JSONObject.parseObject(jsonMsg);
            WmsMsgTypeEnums msgTypeEnums = WmsMsgTypeEnums.parse(Integer.valueOf(jsonObject.getString("businessCode"))).orElseThrow(()->new WmsBusinessException("未知消息!"));
            switch (msgTypeEnums.getCode()){
                //单参数
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                case 6:
                    String relateBusinessId = jsonObject.getString("relateBusinessId");
                    this.doSingleParamInvoke(msgTypeEnums,relateBusinessId);
                    break;
                //多参数
                case 7:
                    String tableName = jsonObject.getString("tableName");
                    String dataId = jsonObject.getString("dataId");
                    String dataContent = jsonObject.getString("dataContent");
                    this.doMultiParamInvoke(msgTypeEnums,tableName,dataId,dataContent);
                    break;
                default:
            }
            msg.setMsgStatus(WmsMsgStatusEnums.SUCCESS.getValue());
            msg.setRemark("");
        }catch (Exception e){
            msg.setMsgStatus(WmsMsgStatusEnums.FAIL.getValue());
            msg.setRemark(e.getCause().getMessage());
        }finally {
            asyncMsgService.saveOrUpdate(msg);
        }
    }

    private void doMultiParamInvoke(WmsMsgTypeEnums msgTypeEnums, String ...businessCode) throws Exception{
        Object agentService = SpringContextUtils.getBean(msgTypeEnums.getServiceName());
        Class[] argsClass = new Class[businessCode.length];
        for (int i = 0, j = businessCode.length; i < j; i++) {
            argsClass[i] = businessCode[i].getClass();
        }
        Method agentMethod = agentService.getClass().getMethod(msgTypeEnums.getMethodName(),argsClass);
        agentMethod.invoke(agentService,businessCode);
    }

    private void doSingleParamInvoke(WmsMsgTypeEnums msgTypeEnums, String businessCode) throws Exception {
        Object agentService = SpringContextUtils.getBean(msgTypeEnums.getServiceName());
        Method agentMethod = agentService.getClass().getMethod(msgTypeEnums.getMethodName(),new Class[]{String.class});
        agentMethod.invoke(agentService,new String[]{businessCode});
    }
}
